//
//  JMDrawingProtocol.swift
//  JMDrawingLayer
//
//  Created by JunMing on 2021/1/29.
//

import UIKit

public protocol JMDrawingProtocol { }

extension JMDrawingProtocol {
    /// 起点
    /// - Parameter startPoint: 开始点
    public func movePath(startPoint point: CGPoint) { }
    
    /// 终点
    /// - Parameter endPoint: 结束点
    public func movePath(endPoint point: CGPoint) { }
    
    public func arrowWithPoint(startPoint: CGPoint, endPoint: CGPoint) -> UIBezierPath {
        var controllPoint = CGPoint.zero
        var pointUp = CGPoint.zero
        var pointDown = CGPoint.zero
        let distance = distanceWithPoint(startPoint, endPoint)
        
        let distanceX = 8.0 * (fabsf((endPoint.x - startPoint.x).fvalue).cvalue / distance)
        let distanceY = 8.0 * (fabsf((endPoint.y - startPoint.y).fvalue).cvalue / distance)
        let distX =  distanceX / 2.0 // 4.0 * (fabsf((endPoint.x - startPoint.x).fvalue).cvalue / distance)
        let distY = distanceY / 2.0  // 4.0 * (fabsf((endPoint.x - startPoint.x).fvalue).cvalue / distance)
        
        if endPoint.x >= startPoint.x {
            if endPoint.y >= startPoint.y {
                controllPoint = CGPoint.Make(endPoint.x - distanceX, endPoint.y - distanceY);
                pointUp = CGPoint.Make(controllPoint.x + distX, controllPoint.y - distY);
                pointDown = CGPoint.Make(controllPoint.x - distX, controllPoint.y + distY);
            }else {
                controllPoint = CGPoint.Make(endPoint.x - distanceX, endPoint.y + distanceY);
                pointUp = CGPoint.Make(controllPoint.x - distX, controllPoint.y - distY);
                pointDown = CGPoint.Make(controllPoint.x + distX, controllPoint.y + distY);
            }
        }else {
            if (endPoint.y >= startPoint.y)
            {
                controllPoint = CGPoint.Make(endPoint.x + distanceX, endPoint.y - distanceY);
                pointUp = CGPoint.Make(controllPoint.x - distX, controllPoint.y - distY);
                pointDown = CGPoint.Make(controllPoint.x + distX, controllPoint.y + distY);
            } else {
                controllPoint = CGPoint.Make(endPoint.x + distanceX, endPoint.y + distanceY);
                pointUp = CGPoint.Make(controllPoint.x + distX, controllPoint.y - distY);
                pointDown = CGPoint.Make(controllPoint.x - distX, controllPoint.y + distY);
            }
        }
        
        let arrowPath = UIBezierPath()
        arrowPath.move(to: endPoint)
        arrowPath.addLine(to: pointDown)
        arrowPath.addLine(to: pointUp)
        arrowPath.addLine(to: endPoint)
        return arrowPath
    }
    
    public func distanceWithPoint(_ startPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
        let xDist = endPoint.x - startPoint.x
        let yDist = endPoint.y - startPoint.y
        return sqrt(xDist * xDist + yDist * yDist)
    }
    
    public func angleWithFirstPoint(firstPoint: CGPoint, secondPoint: CGPoint) -> CGFloat {
        let xDist = secondPoint.x - firstPoint.x
        let yDist = secondPoint.y - firstPoint.y
        return atan2f(yDist.fvalue, xDist.fvalue).cvalue
    }
    
    public func angleEndWithFirstPoint(firstPoint: CGPoint, secondPoint: CGPoint) -> CGFloat {
        let xDist = secondPoint.x - firstPoint.x
        let yDist = secondPoint.y - firstPoint.y
        let angle = atan2f(fabs(xDist.dvalue).fvalue, fabs(yDist.dvalue).fvalue).cvalue
        if xDist * yDist > 0 {
            return Double.pi.cvalue - angle
        }else {
            return angle
        }
    }
}
